package com.ruibang.glass.file.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruibang.glass.file.constant.Constants;
import com.ruibang.glass.file.constant.FileErrorCode;
import com.ruibang.glass.file.domain.req.DirInfo;
import com.ruibang.glass.file.domain.req.FolderInfoReq;
import com.ruibang.glass.file.entity.FileInfo;
import com.ruibang.glass.file.entity.FolderInfo;
import com.ruibang.glass.file.mapper.FolderInfoMapper;
import com.ruibang.glass.file.service.FileService;
import com.ruibang.glass.file.service.FolderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 文件夹信息 服务实现类
 * </p>
 *
 * @author songJinKang
 * @since 2024-04-15
 */
@Slf4j
@Service
public class FolderInfoServiceImpl extends ServiceImpl<FolderInfoMapper, FolderInfo> implements FolderInfoService {

    @Autowired
    private FileService fileService;

    /**
     * @Description: 文件夹上传
     * @version v1.0
     * @author songJinKang
     * @date 2024-04-15 11:37
     */
    @Override
    public void upload(List<FolderInfo> folderInfos) {
        if (CollectionUtils.isNotEmpty(folderInfos)) {
            for (FolderInfo folderInfo : folderInfos) {
                if (Constants.ZERO_STR.equals(folderInfo.getIsDir()) && StringUtils.isBlank(folderInfo.getFileId())) {
                    throw new ServiceException(FileErrorCode.IS_DIR_FILE_ID_NOT_NULL.getCode(), FileErrorCode.IS_DIR_FILE_ID_NOT_NULL.getMsg());
                }
                if (!Constants.RIGHT_SLASH.equals(folderInfo.getTargetPath())) {
                    folderInfo.setPath(folderInfo.getTargetPath().concat(folderInfo.getPath()));
                }
                //已经创建的文件夹
                Map<String, Integer> createDirMap = new HashMap<>(16);

                //处理文件
                processFolderInfo(folderInfo, createDirMap);
            }
            //保存文件
            this.saveBatch(folderInfos);
        }
    }

    private void processFolderInfo(FolderInfo folderInfo, Map<String, Integer> createDirMap) {
        String path = folderInfo.getPath();
        String[] split = path.split("/");
        String[] pathNames = removeFirstAndLast(split);
        log.error("path:{}       pathNames:{}", path, Arrays.toString(pathNames));
        if (pathNames.length > 0) {
            for (int i = 0; i < pathNames.length; i++) {
                //判断是否创建文件夹
                if (i == 0) {
                    String dirName = pathNames[i];
                    String dirPath = "/";

                    //创建文件夹
                    Long count = lambdaQuery().eq(FolderInfo::getPath, dirPath).eq(FolderInfo::getFileName, dirName).eq(FolderInfo::getIsDelete, Constants.ZERO_STR)
                            .eq(FolderInfo::getBusinessId, folderInfo.getBusinessId()).eq(FolderInfo::getIsDir, Constants.ONE_STR).count();
                    if (count == null || count == 0) {
                        FolderInfo dirInfo = new FolderInfo();
                        dirInfo.setBusinessId(folderInfo.getBusinessId());
                        dirInfo.setPath(dirPath);
                        dirInfo.setFileName(dirName);
                        dirInfo.setIsDir(Constants.ONE_STR);
                        this.save(dirInfo);
                    } else {
                        //放入Map

                    }
                } else {
                    StringBuilder dirPathName = new StringBuilder("/");
                    for (int j = 0; j <= i; j++) {
                        if (i == j) {
                            dirPathName.append(pathNames[j]);
                        } else {
                            dirPathName.append(pathNames[j]).append("/");
                        }
                    }
                    //创建文件夹
                    createDir(dirPathName.toString(), folderInfo, createDirMap);
                }
            }
        }

        //处理文件的路径与名称
        String fileName = extractDirName(path);
        String filepath = extractDirPath(path);
        Long count = lambdaQuery().eq(FolderInfo::getBusinessId, folderInfo.getBusinessId()).eq(FolderInfo::getPath, filepath)
                .eq(FolderInfo::getIsDir, Constants.ZERO_STR).eq(FolderInfo::getIsDelete, Constants.ZERO_STR).eq(FolderInfo::getFileName, fileName).count();
        if (count == null || count == 0) {
            folderInfo.setFileName(fileName);
            folderInfo.setPath(filepath);
            folderInfo.setIsDir(Constants.ZERO_STR);
        } else {
            folderInfo.setFileName(String.valueOf(System.currentTimeMillis()).concat("_").concat(fileName));
            folderInfo.setPath(filepath);
            folderInfo.setIsDir(Constants.ZERO_STR);
        }
        //修改上级文件夹修改时间
        modifyDirUpdateTime(filepath);
    }

    private void modifyDirUpdateTime(String dirPath) {
        if (!Constants.RIGHT_SLASH.equals(dirPath)) {
            String upDirName = extractDirName(dirPath);
            String upDirPath = extractDirPath(dirPath);
            FolderInfo upFolderInfo = lambdaQuery().eq(FolderInfo::getIsDelete, Constants.ZERO_STR).eq(FolderInfo::getPath, upDirPath)
                    .eq(FolderInfo::getFileName, upDirName).eq(FolderInfo::getIsDir, Constants.ONE_STR).one();
            if (upFolderInfo != null) {
                upFolderInfo.setUpdateTime(LocalDateTime.now());
                this.updateById(upFolderInfo);
            }
        }
    }


    public static void main(String[] args) {
        String test = "/nginx/30/1/2/3";
        String dirName = extractDirName(test);
        String path = extractDirPath(test);
        System.out.println(dirName);
        System.out.println(path);
    }

    /**
     * @Description: 创建文件夹
     * @version v1.0
     * @author songJinKang
     * @date 2024-04-15 15:56
     */
    private void createDir(String dirPath, FolderInfo folderInfo, Map<String, Integer> createDirMap) {
        //截取文件夹名称
        String dirName = extractDirName(dirPath);
        String dirFilePath = extractDirPath(dirPath);
        folderInfo.setFileName(dirName);
        folderInfo.setPath(dirPath);
        folderInfo.setIsDir(Constants.ZERO_STR);
        Long count = lambdaQuery().eq(FolderInfo::getPath, dirFilePath).eq(FolderInfo::getFileName, dirName).eq(FolderInfo::getIsDelete, Constants.ZERO_STR)
                .eq(FolderInfo::getBusinessId, folderInfo.getBusinessId()).eq(FolderInfo::getIsDir, Constants.ONE_STR).count();
        if (count == null || count == 0) {
            FolderInfo dirInfo = new FolderInfo();
            dirInfo.setBusinessId(folderInfo.getBusinessId());
            dirInfo.setPath(dirFilePath);
            dirInfo.setFileName(dirName);
            dirInfo.setIsDir(Constants.ONE_STR);
            this.save(dirInfo);
        } else {
            //放入Map
        }
    }


    private static String extractDirName(String path) {
        int lastSlashIndex = path.lastIndexOf(Constants.RIGHT_SLASH);
        if (lastSlashIndex != -1) {
            return path.substring(lastSlashIndex + 1);
        }
        return "";
    }


    private static String extractDirPath(String path) {
        int lastSlashIndex = path.lastIndexOf(Constants.RIGHT_SLASH);
        if (lastSlashIndex > 0) {
            return path.substring(0, lastSlashIndex);
        }
        return Constants.RIGHT_SLASH;
    }

    private static String[] removeFirstAndLast(String[] array) {
        // 如果数组长度小于等于2，则返回空数组
        if (array.length <= 2) {
            return new String[0];
        }
        // 创建新数组，长度为原数组长度减2
        String[] newArray = new String[array.length - 2];
        // 复制除去头尾元素的部分到新数组中
        System.arraycopy(array, 1, newArray, 0, newArray.length);
        return newArray;
    }

    /**
     * @Description: 获取下一级文件夹信息
     * @version v1.0
     * @author songJinKang
     * @date 2024-04-15 14:33
     */
    @Override
    public Page<FolderInfo> getNextDirInfo(FolderInfoReq folderInfoReq) {
        Page<FolderInfo> page = lambdaQuery().eq(FolderInfo::getIsDelete, Constants.ZERO_STR).eq(FolderInfo::getBusinessId, folderInfoReq.getBusinessId())
                .orderByDesc(FolderInfo::getIsDir, FolderInfo::getCreateTime, FolderInfo::getUpdateTime).eq(FolderInfo::getPath, folderInfoReq.getPath()).page(new Page<>(folderInfoReq.getPageNo(), folderInfoReq.getPageSize()));
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            List<FolderInfo> folderInfoList = page.getRecords();
            List<String> fileIds = folderInfoList.stream().filter(e -> Constants.ZERO_STR.equals(e.getIsDir())).map(FolderInfo::getFileId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(fileIds)) {
                List<FileInfo> fileInfos = fileService.getFileInfoByFileIds(fileIds);
                if (CollectionUtils.isNotEmpty(fileInfos)) {
                    Map<String, FileInfo> fileMap = fileInfos.stream().collect(Collectors.toMap(FileInfo::getFileId, e -> e));
                    folderInfoList.forEach(e -> {
                        if (Constants.ZERO_STR.equals(e.getIsDir())) {
                            FileInfo fileInfo = fileMap.get(e.getFileId());
                            if (fileInfo != null) {
                                e.setFileAddress(fileInfo.getFileAddress());
                                e.setFileSize(fileInfo.getFileSize());
                            }
                        }
                    });
                }
            }
        }
        return page;
    }


    /**
     * @Description: 删除文件
     * @version v1.0
     * @author songJinKang
     * @date 2024-04-15 14:33
     */
    @Override
    public void deleteById(String id) {
        if (StringUtils.isNotBlank(id)) {
            //获取当前文件
            FolderInfo folderInfo = this.getById(id);
            if (folderInfo != null) {
                if (Constants.ONE_STR.equals(folderInfo.getIsDir())) {
                    //判断是否还有子级
                    String path = folderInfo.getPath().concat("/").concat(folderInfo.getFileName());
                    List<FolderInfo> sonFolderInfo = lambdaQuery().eq(FolderInfo::getIsDelete, Constants.ZERO_STR).likeRight(FolderInfo::getPath, path).eq(FolderInfo::getBusinessId, folderInfo.getBusinessId()).list();
                    if (CollectionUtils.isNotEmpty(sonFolderInfo)) {
                        List<String> ids = sonFolderInfo.stream().map(FolderInfo::getId).collect(Collectors.toList());
                        lambdaUpdate().set(FolderInfo::getIsDelete, Constants.ONE_STR).in(FolderInfo::getId, ids).update();
                    }
                }
            } else {
                throw new ServiceException(FileErrorCode.DELETE_ITEM_NO_EXIST.getCode(), FileErrorCode.DELETE_ITEM_NO_EXIST.getMsg());
            }
            //更新
            lambdaUpdate().set(FolderInfo::getIsDelete, Constants.ONE_STR).eq(FolderInfo::getId, id).update();
            //修改上级文件夹修改时间
            modifyDirUpdateTime(folderInfo.getPath());
        }
    }

    @Override
    public void createDir(DirInfo dirInfo) {
        //判断是否有重复的文件夹
        Long count = lambdaQuery().eq(FolderInfo::getPath, dirInfo.getTargetPath()).eq(FolderInfo::getFileName, dirInfo.getFileName()).eq(FolderInfo::getIsDelete, Constants.ZERO_STR)
                .eq(FolderInfo::getBusinessId, dirInfo.getBusinessId()).eq(FolderInfo::getIsDir, Constants.ONE_STR).count();
        if (count != null && count > 0) {
            throw new ServiceException(FileErrorCode.DIR_IS_EXIST.getCode(), FileErrorCode.DIR_IS_EXIST.getMsg());
        }
        FolderInfo folderInfo = new FolderInfo();
        folderInfo.setBusinessId(dirInfo.getBusinessId());
        folderInfo.setPath(dirInfo.getTargetPath());
        folderInfo.setFileName(dirInfo.getFileName());
        folderInfo.setIsDir(Constants.ONE_STR);
        //修改上级文件夹修改时间
        modifyDirUpdateTime(folderInfo.getPath());
        this.save(folderInfo);
    }
}
